<script setup lang="ts">
import { ref, computed } from 'vue';
import type { Trademark } from '@/api/product/type.ts';
import { reqImgUpload } from '@/api/upload.ts';
import { useQuasar, QForm } from 'quasar';
import { useCompRef } from '@/utils/useCompRef.ts';
import { reqAddOrUpdateTrademark } from '@/api/product/trademark.ts';
import { quasarFormStyle } from '@/setting.ts';

const emit = defineEmits(['refreshData']);
const $q = useQuasar();
// 对话框表单数据
const trademarkForm = ref<Trademark>({
  tmName: '',
  logoUrl: ''
});
// 是否显示表单对话框
const isShowDialog = ref(false);
// 显示表单对话框
function showDialog(trademark: Trademark = { tmName: '', logoUrl: '' }) {
  // 不能使用原对象
  trademarkForm.value = { ...trademark };
  fileImg.value = null;
  isShowDialog.value = true;
}
defineExpose({ showDialog });
// 计算标题
const title = computed(() => {
  return trademarkForm.value.id ? '修改品牌' : '添加品牌';
});
// 上传图片
const fileImg = ref<File | null>();
async function uploadImg(file: File) {
  try {
    // 图片格式只能是jpg png 最大不能超过2mb
    if (!/\.(jpg|png)$/i.test(file.name)) {
      throw new Error('图片格式只能是jpg png');
    }
    if (file.size > 2 * 1024 * 1024) {
      throw new Error('图片大小不能超过2MB');
    }
    // 选择后在本地生成预览图 生成dataUrl用于src
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = e => {
      trademarkForm.value.logoUrl = e.target!.result as string;
    };
    // 上传到服务器 FormData格式
    const formData = new FormData();
    formData.append('file', file);
    const res = await reqImgUpload(formData);
    if (res.code === 200) {
      trademarkForm.value.logoUrl = res.data;
    } else {
      throw new Error('图片上传失败');
    }
  } catch (error: any) {
    fileImg.value = null;
    $q.notify({
      type: 'negative',
      message: error.message,
      position: 'top'
    });
  }
}
// 表单组件
const qFormCom = useCompRef(QForm);
// 提交数据
async function submitTrademark() {
  const error = await qFormCom.value?.validate();
  // 检验不通过
  if (!error) return;
  try {
    if (!trademarkForm.value.logoUrl) throw new Error('请选择图片');
    // 图片上传失败 上传成功src应该是http
    if (!trademarkForm.value.logoUrl.startsWith('http'))
      throw new Error('图片未上传');
    // 发起请求
    const res = await reqAddOrUpdateTrademark(trademarkForm.value);
    if (res.code === 200) {
      $q.notify({
        type: 'positive',
        message: `${title.value}成功`,
        position: 'top'
      });
      emit('refreshData');
      isShowDialog.value = false;
    } else {
      throw new Error(`${title.value}失败`);
    }
  } catch (error: any) {
    $q.notify({
      type: 'negative',
      message: error.message,
      position: 'top'
    });
  }
}
</script>

<template>
  <!-- code... -->
  <q-dialog v-model="isShowDialog">
    <q-card class="q-dialog-plugin">
      <q-card-section>
        <span class="text-h6">{{ title }}</span>
      </q-card-section>
      <q-card-section>
        <q-form class="q-pl-lg" ref="qFormCom">
          <q-input
            label="品牌名称"
            v-model="trademarkForm.tmName"
            :rules="[
              val => !!val || '品牌名称不能为空',
              val => val.length >= 3 || '品牌名称不能小于三个字符'
            ]"
            :lazy-rules="true"
            v-bind="quasarFormStyle"
          />
          <!-- 占位标题 readonly禁用交互动画 -->
          <q-field label="品牌LOGO" borderless readonly></q-field>
          <!-- 只能上传jpg png格式 大小不能超过2mb -->
          <q-file
            v-model="fileImg"
            class="upload q-mt-xs"
            borderless
            @update:model-value="uploadImg"
            no-error-icon
            hide-bottom-space
          >
            <!-- hide-bottom-space 让错误信息移动到容器外部，但也禁用了动画效果 -->
            <template #default>
              <q-icon
                class="plus"
                name="add"
                size="lg"
                v-if="!trademarkForm.logoUrl"
              ></q-icon>
              <q-img class="img" :src="trademarkForm.logoUrl" v-else></q-img>
            </template>
            <!-- 覆盖默认文件内容 -->
            <template #file></template>
          </q-file>
        </q-form>
      </q-card-section>
      <q-card-actions align="right">
        <q-btn
          label="取消"
          color="primary"
          flat
          @click="isShowDialog = false"
        />
        <q-btn label="提交" color="primary" @click="submitTrademark" />
      </q-card-actions>
    </q-card>
  </q-dialog>
</template>

<style scoped lang="scss">
.upload {
  position: relative;
  width: 200px;
  height: 200px;
  border: 1px solid #ddd;

  :deep(.q-field__control) {
    height: 100%;
  }

  .plus {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    color: #ddd;
  }

  .img {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
  }
}
</style>
